package com.kay.proxy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kay.common.RPCRequest;
import com.kay.common.RPCResponse;
import com.kay.config.RPCServerConfig;
import com.kay.server.RPCClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description: 客户端代理类-创建代理对象
 * 1.封装request请求对象
 * 2.创建RpcClient对象
 * 3.发送消息
 * 4.返回结果
 * @Author: Kay
 * @CreateDate: 2021/8/27$ 20:13$
 * @UpdateUser: Kay
 * @UpdateDate: 2021/8/27$ 20:13$
 */
@Component
public class RpcClientProxy {

    @Autowired
    private RPCServerConfig rpcServerConfig;

    /**
     * 自定义轮询
     */
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement() {
        int current;
        int next;
        do {
            current = this.atomicInteger.get();
            next = current >= 214748364 ? 0 : current + 1;
        } while (!this.atomicInteger.compareAndSet(current, next));
        System.out.println("next:" + next);
        return next;
    }

    public RPCClient getClient() {
        List<String> ipList = rpcServerConfig.getIpList();
        int i = getAndIncrement() % ipList.size();
        List<Integer> portList = rpcServerConfig.getPortList();
        return new RPCClient(ipList.get(i), portList.get(i));
    }

    public Object createProxy(Class classObject) {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[]{classObject}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 封装request请求对象
                        RPCRequest request = new RPCRequest();
                        request.setRequestId(UUID.randomUUID().toString());
                        request.setClassName(method.getDeclaringClass().getName());
                        request.setMethodName(method.getName());
                        request.setParameters(args);
                        request.setParameterTypes(method.getParameterTypes());
                        // 创建RpcClient对象
                        RPCClient rpcClient = getClient();
                        rpcClient.initClient();
                        try {
                            // 发送消息
                            Object response = rpcClient.request(JSONObject.toJSONString(request));
                            // 封装返回结果
                            RPCResponse rpcResponse = JSONObject.parseObject(response.toString(), RPCResponse.class);
                            if (rpcResponse.getError() != null) {
                                throw new RuntimeException(rpcResponse.getError());
                            }
                            // 返回结果
                            Object result = rpcResponse.getResult();
                            return JSON.parseObject(result.toString(), method.getReturnType());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            rpcClient.close();
                        }
                        return null;
                    }
                });
    }
}
